package engine.game;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.text.DecimalFormat;

import javax.swing.JPanel;

import engine.Engine;
import engine.Logger;
import engine.Util;

@SuppressWarnings("serial")
public class BasePanel extends JPanel implements Runnable {
	public static final int DEFAULT_WIDTH = 640;
	public static final int DEFAULT_HEIGHT = 480;

	private Logger logger;
	private GraphicsDevice gd;
	private int accelMemory;
	private DecimalFormat df;

	private Thread animator;
	private BaseGame game;

	public BasePanel(Engine engine) {
		super();
		logger = Logger.getInstance();
		
		df = new DecimalFormat("0.0");
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		gd = ge.getDefaultScreenDevice();
		
		accelMemory = gd.getAvailableAcceleratedMemory();
		logger.out(Logger.DEV, "Initial Acc. Mem.: " + df.format(((double) accelMemory) / (1024 * 1024)) + " MB");
		
		setBackground(Color.WHITE);
		
		int window_width = Util.parseInt(engine.getConfig("window_width"));
		int window_height = Util.parseInt(engine.getConfig("window_height"));
		
		if (window_width == 0) {
			window_width = DEFAULT_WIDTH;
		}
		
		if (window_height == 0) {
			window_height = DEFAULT_HEIGHT;
		}
		
		setPreferredSize(new Dimension(window_width, window_height));
	}

	@Override
	public void addNotify() {
		super.addNotify();
		
		if (game == null) {
			logger.out(Logger.ERROR, "Game is not set.");
			return;
		}
		
		if (animator == null || !game.isRunning()) {
			animator = new Thread(this);
			animator.start();
		}
	}

	@Override
	public void run() {
		long beforeTime, afterTime, timeDiff, sleepTime;
		long overSleepTime = 0L;
		int noDelays = 0;
		long excess = 0L;
		
		beforeTime = getTimeInNanoSecond();
		game.setRunning(true);
		
		while(game.isRunning()) {
			game.update();
			renderGame();
		}
	}

	protected void renderGame() {
		Graphics g;
		
		g = getGraphics();
		
	}

	private void paintScreen() {
		
	}

	public long getTimeInNanoSecond() {
		return System.nanoTime();
	}

	public void setGame(BaseGame game) {this.game = game;}

}